• It is a Unity Implementation of "Chase & Tag", where one player has to chase the other to win and the other player has to survive for some time to attain victory.
• It features local multiplayer input system, with one player assigned WASD and the other the arrow keys (←↑↓→) for movement.
• One of the players will randomly be assigned the chaser role while the other will be the survivor or runner.
• The chaser will be crowned winner if they tag the survivor before time runs out, otherwise the survivor wins. If any player falls off the platform then the opposing player wins.
• The game also includes abilities such as extra speed, which provides extra zing to the game and keeps it interesting for both players.
• The main motivation behind this project is learning. I wanted to learn how to implement an existing game concept.
• The project also helped with my Unity programming skills, specifically the input system and multiple camera management.
• Implemented the multiplayer input and camera system.
• Designed the main level with all of the hurdles and abilities using ProBuilder.
• Programmed the abilities and main game loop.
• Built the UI/UX using Unity UI widgets.
public void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "Player")
{
CheckCollisionAndEndGame(collision);
}
if(collision.transform.tag == "End Collider")
{
for(int i=0; i<2; i++)
{
if(players[i].transform.name != this.transform.name)
{
if(!GameObject.FindGameObjectWithTag("Winner Manager").GetComponent<WinnerManager>().winnerDecided)
{
wonPlayerName.text = players[i].transform.name;
finalScreen.gameObject.SetActive(true);
GameObject.FindGameObjectWithTag("Winner Manager").GetComponent<WinnerManager>().winnerDecided = true;
}
}
}
}
}
public void CheckCollisionAndEndGame(Collision collision)
{
if (!GameObject.FindGameObjectWithTag("Winner Manager").GetComponent<WinnerManager>().winnerDecided)
{
if ((this.gameObject.GetComponent<RoleCumRoundManager>().isAttacker && collision.gameObject.GetComponent<RoleCumRoundManager>().isDefender))
{
print("Game has Ended");
wonPlayerName.text = this.transform.name;
finalScreen.gameObject.SetActive(true);
GameObject.FindGameObjectWithTag("Winner Manager").GetComponent<WinnerManager>().winnerDecided = true;
}
if ((this.gameObject.GetComponent<RoleCumRoundManager>().isDefender && collision.gameObject.GetComponent<RoleCumRoundManager>().isAttacker))
{
print("Game has Ended");
wonPlayerName.text = collision.transform.name;
finalScreen.gameObject.SetActive(true);
GameObject.FindGameObjectWithTag("Winner Manager").GetComponent<WinnerManager>().winnerDecided = true;
}
}
}
Full Script (GitHub)
This code can be easily improved by reducing expensive calls to FindGameObjectWithTag (either use singleton pattern or cache the reference), replacing tag and name checks with references or IDs, and cleaning the role checks for better readability and maintenance.
Win Screen (by Falling Off):
Win Screen (by Timer):